package com.yygo.service.impl;

import com.yygo.Constants;
import com.yygo.dao.CommissionTransferDao;
import com.yygo.dao.LoanRequestDao;
import com.yygo.dao.MoneyTransferDao;
import com.yygo.dao.PrepaymentDao;
import com.yygo.model.*;
import com.yygo.model.enums.TransferType;
import com.yygo.service.MoneyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by tiansha on 2015/11/28.
 */
@Service("moneyService")
public class MoneyServiceImpl implements MoneyService {

    @Autowired
    private PrepaymentDao prepaymentDao;

    @Autowired
    private MoneyTransferDao moneyTransferDao;

    @Autowired
    private LoanRequestDao loanRequestDao;

    @Autowired
    private CommissionTransferDao commissionTransferDao;

    @Override
    public BigDecimal calculateLoanAmount(LoanRequest loanRequest) {
        BigDecimal baseLoanAmount = BigDecimal.valueOf(loanRequest.getLoanAmount());
        LoanProduct loanProduct = loanRequest.getLoanProduct();
        BigDecimal feeRate = BigDecimal.valueOf(loanRequest.getFeeRate()).divide(BigDecimal.valueOf(100));
        BigDecimal costRate = BigDecimal.valueOf(loanProduct.getCostRate()).divide(BigDecimal.valueOf(100));
        return baseLoanAmount.multiply(BigDecimal.valueOf(1).add(feeRate).subtract(costRate));
    }

    @Override
    public BigDecimal calculateMonthLoanAmount(LoanRequest loanRequest) {
        LoanProduct loanProduct = loanRequest.getLoanProduct();
        BigDecimal costRate = BigDecimal.valueOf(loanProduct.getCostRate()).divide(BigDecimal.valueOf(100));
        BigDecimal loanAmount = calculateLoanAmount(loanRequest);
        return loanAmount.multiply(BigDecimal.valueOf(1).add(costRate)).divide(BigDecimal.valueOf(loanRequest.getLoanYears()*12));
    }

    @Override
    @Transactional
    public void approvePrepayment(Long payId, String operator) {
        Prepayment prepayment = prepaymentDao.get(payId);
        prepayment.setOperator(operator);
        prepayment.setStatus(Constants.STATUS_APPROVED);
        prepaymentDao.save(prepayment);

        // generate transfer record
        LoanRequest loanRequest = prepayment.getLoanRequest();
        BondCompany bondCompany = prepayment.getBondCompany();
        MoneyTransferRecord moneyTransferRecord = new MoneyTransferRecord();
        moneyTransferRecord.setLoanRequest(loanRequest);
        moneyTransferRecord.setAuditOperator(operator);
        moneyTransferRecord.setStatus(Constants.STATUS_PENDING);
        moneyTransferRecord.setAmount(calculateLoanAmount(loanRequest).floatValue());

        // set dealer's account
        Dealer dealer = loanRequest.getDealer();
        moneyTransferRecord.setBank(dealer.getBank());
        moneyTransferRecord.setBankAccount(dealer.getBankAccount());
        moneyTransferRecord.setCardName(dealer.getCardName());

        moneyTransferRecord.setGenerateDate(new Date());
        moneyTransferRecord.setMemo("由" + bondCompany.getName() + "垫资");
        moneyTransferRecord.setType(TransferType.Prepayment);
        moneyTransferRecord.setBondCompany(bondCompany);

        moneyTransferDao.save(moneyTransferRecord);
    }

    @Override
    @Transactional
    public void approveTransfer(Long reqId, String operator) {
        LoanRequest loanRequest = loanRequestDao.loadWholeLoanRequest(reqId);

        // generate transfer record
        MoneyTransferRecord moneyTransferRecord = new MoneyTransferRecord();
        moneyTransferRecord.setLoanRequest(loanRequest);
        moneyTransferRecord.setAuditOperator(operator);
        moneyTransferRecord.setStatus(Constants.STATUS_PENDING);
        moneyTransferRecord.setAmount(calculateLoanAmount(loanRequest).floatValue());

        Prepayment prepayment = prepaymentDao.getPrepayment(loanRequest);

        if (prepayment == null) {
            // set dealer's account
            Dealer dealer = loanRequest.getDealer();
            moneyTransferRecord.setBank(dealer.getBank());
            moneyTransferRecord.setBankAccount(dealer.getBankAccount());
            moneyTransferRecord.setCardName(dealer.getCardName());
            moneyTransferRecord.setMemo("车款");
        } else {
            BondCompany bondCompany = prepayment.getBondCompany();
            moneyTransferRecord.setBank(bondCompany.getBank());
            moneyTransferRecord.setBankAccount(bondCompany.getBankAccount());
            moneyTransferRecord.setCardName(bondCompany.getCardName());
            moneyTransferRecord.setMemo("已垫资给" + loanRequest.getDealer().getName());
        }

        moneyTransferRecord.setGenerateDate(new Date());
        moneyTransferRecord.setType(TransferType.LoanMoney);

        moneyTransferDao.save(moneyTransferRecord);
    }

    @Override
    @Transactional
    public void transferMoney(Long id, String operator) {
        // do transfer money

        // update money transfer record
        MoneyTransferRecord record = moneyTransferDao.get(id);
        record.setTransferOperator(operator);
        Calendar currentDate = Calendar.getInstance();
        record.setTransferDate(currentDate.getTime());
        record.setSerialNo(""); // TODO
        record.setStatus(Constants.STATUS_TRANSFERRED);

        if (record.getType().equals(TransferType.LoanMoney)) {

            // generate month return records
            Calendar startBillDate = Calendar.getInstance();
            Bank bank = record.getLoanRequest().getLoanProduct().getBank();
            int billDate = bank.getBillDate();
            startBillDate.set(Calendar.DATE, billDate);
            if (billDate > currentDate.get(Calendar.DATE)) {
                startBillDate.roll(Calendar.MONTH, 1);
            }

            for (int i = 0; i < record.getLoanRequest().getLoanYears() * 12; i++) {
                RepayRecord repayRecord = new RepayRecord();
                repayRecord.setMonths(i + 1);
                repayRecord.setMoneyTransferRecord(record);
                repayRecord.setBillDate(startBillDate.getTime());
                // calc deadline
                Calendar temp = (Calendar) startBillDate.clone();
                temp.roll(Calendar.DATE, 25);
                repayRecord.setDeadline(temp.getTime());

                record.getRepayRecords().add(repayRecord);
                startBillDate.roll(Calendar.MONTH, 1);
            }

            CommissionTransferRecord commissionTransferRecord = new CommissionTransferRecord();
            commissionTransferRecord.setLoanRequest(record.getLoanRequest());

            commissionTransferDao.save(commissionTransferRecord);
        }

        moneyTransferDao.save(record);
    }

}
